package com.suqiu.qqrobot.common.result;


import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author suqiu
 * @desc 统一API响应结果封装
 */
@Getter
@Setter
@ToString
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<T> implements Serializable {

    /**
     * 描述成功或失败的常量值,
     * 值为字典表，如 SUCCESS,UNAUTHORIZED,NOT_FOUND...具体参考规范文件 <<API结构规范.docx>>, 前端可以根据此值作条件分支处理
     */
    private String code;

    /**
     * 当有结果返回业务数据时, 其内容是T类型,范型
     */
    private T data;

    /**
     * 当失败时描述具体原因,要求多语言化内容
     */
    private String message;

    /**
     * 服务异常堆栈, 可填项
     */
    private String details;

    private Result(IResultCode result) {
        this.code = result.getCode();
        if (result.equals(ResultCodeEnum.SUCCESS)) {
            //这里特殊处理，其它异常枚举在统一异常处理类中转换
            this.code = ResultCodeEnum.SUCCESS.name();
        }
        this.message = result.getMessage();
        //this.data = (T) new JSONObject();
    }

    private Result(IResultCode result, T data) {
        this.code = result.getCode();
        if (result.equals(ResultCodeEnum.SUCCESS)) {
            //这里特殊处理，其它异常枚举在统一异常处理类中转换
            this.code = ResultCodeEnum.SUCCESS.name();
        }
        this.message = result.getMessage();
        this.data = data;
    }

    private Result(String code, String msg) {
        this(code, null, msg);
    }

    private Result(String code, T data, String msg) {
        this.code = code;
        if (code.equals(ResultCodeEnum.SUCCESS.getCode())) {
            //这里特殊处理，其它异常枚举在统一异常处理类中转换
            this.code = ResultCodeEnum.SUCCESS.name();
        }
        this.data = data;
        this.message = msg;
    }

    private Result(String code, T data, String msg, String details) {
        this.code = code;
        if (code.equals(ResultCodeEnum.SUCCESS.getCode())) {
            //这里特殊处理，其它异常枚举在统一异常处理类中转换
            this.code = ResultCodeEnum.SUCCESS.name();
        }
        this.data = data;
        this.message = msg;
        this.details = details;
    }


    /////////////////////////////////////////
    /////////以下为工具方法, 请在controller或service实现类中调用


    public static <T> Result<T> ok() {
        return new Result<>(ResultCodeEnum.SUCCESS);
    }


    public static <T> Result<T> ok(T data) {
        return new Result<>(ResultCodeEnum.SUCCESS, data);
    }


    //所有的异常在 controller或service的实现类中通过throw new BusinessException(ResultCodeEnum e)业务异常来处理
    //以下的fail方法集是由 统一异常处理来调用

    /**
     * 含自定义的错误异常message
     */
    public static <T> Result<T> fail(ResultCodeEnum resultCode, String msg) {
        return new Result<>(resultCode.name(), msg);
    }


    /**
     * 错误异常message从 ResultCodeEnum中获取
     */
    public static <T> Result<T> fail(ResultCodeEnum resultCode) {
        return new Result<>(resultCode.name(), resultCode.getMessage());

    }

    /**
     * 对应模块业务异常
     * @param resultCode 所有继承自 {@link IResultCode}
     */
    public static <T> Result<T> fail(IResultCode resultCode) {
        return new Result<>(resultCode.name(), resultCode.getMessage());
    }

    public boolean checkSuccess(){
        return ResultCodeEnum.SUCCESS.name().equals(this.code);
    }


}

